package com.cah.project.module.generate.enums;

import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 功能描述: 数据库字段类型 <br/>
 */
@Getter
@AllArgsConstructor
public enum ColumnTypeEnum {

    NONE("", Type.NONE),

    CHAR("char", Type.STRING),
    VARCHAR("varchar", Type.STRING),
    NARCHAR("narchar", Type.STRING),
    VARCHAR2("varchar2", Type.STRING),
    TINYTEXT("tinytext", Type.STRING) {
        @Override
        public HtmlTypeEnum getHtmlTypeEnum(String columnType) {
            return HtmlTypeEnum.TEXTAREA;
        }
    },
    TEXT("text", Type.STRING) {
        @Override
        public HtmlTypeEnum getHtmlTypeEnum(String columnType) {
            return HtmlTypeEnum.TEXTAREA;
        }
    },
    MEDIUMTEXT("mediumtext", Type.STRING) {
        @Override
        public HtmlTypeEnum getHtmlTypeEnum(String columnType) {
            return HtmlTypeEnum.TEXTAREA;
        }
    },
    LONGTEXT("longtext", Type.STRING) {
        @Override
        public HtmlTypeEnum getHtmlTypeEnum(String columnType) {
            return HtmlTypeEnum.TEXTAREA;
        }
    },

    DATETIME("datetime", Type.TIME) {
        @Override
        public HtmlTypeEnum getHtmlTypeEnum(String columnType) {
            return HtmlTypeEnum.DATETIME;
        }
    },
    TIME("time", Type.TIME) {
        @Override
        public HtmlTypeEnum getHtmlTypeEnum(String columnType) {
            return HtmlTypeEnum.DATETIME;
        }
    },
    DATE("date", Type.TIME) {
        @Override
        public HtmlTypeEnum getHtmlTypeEnum(String columnType) {
            return HtmlTypeEnum.DATETIME;
        }
    },
    TIMESTAMP("timestamp", Type.TIME) {
        @Override
        public HtmlTypeEnum getHtmlTypeEnum(String columnType) {
            return HtmlTypeEnum.DATETIME;
        }
    },

    TINYINT("tinyint", Type.INTEGER),
    SMALLINT("smallint", Type.INTEGER),
    MEDIUMINT("mediumint", Type.INTEGER),
    INT("int", Type.INTEGER),
    INTEGER("integer", Type.INTEGER),

    LONG("long", Type.LONG),

    NUMBER("number", Type.NUMBER),
    FLOAT("float", Type.NUMBER),
    DOUBLE("double", Type.NUMBER),
    DECIMAL("decimal", Type.NUMBER),
    ;

    public static String
    getJavaType(String columnType) {
        String dataType = StrUtil.subBefore(columnType, '(', false);
        return ColumnTypeEnum.indexOf(dataType).getType().getJavaType(columnType);
    }

    public static String getHtmlType(String columnType) {
        String dataType = StrUtil.subBefore(columnType, '(', false);
        return ColumnTypeEnum.indexOf(dataType).getHtmlTypeEnum(columnType).getCode();
    }

    public HtmlTypeEnum getHtmlTypeEnum(String columnType) {
        return HtmlTypeEnum.INPUT;
    }

    private static final Map<String, ColumnTypeEnum> map = Stream.of(values()).collect(Collectors.toMap(ColumnTypeEnum::getCode, e -> e));

    public static ColumnTypeEnum indexOf(String code) {
        return Optional.ofNullable(map.get(code)).orElse(NONE);
    }

    private enum Type {
        NONE {
            @Override
            public String getJavaType(String columnType) {
                return String.class.getSimpleName();
            }
        },
        STRING {
            @Override
            public String getJavaType(String columnType) {
                return String.class.getSimpleName();
            }
        },
        TIME {
            @Override
            public String getJavaType(String columnType) {
                return Date.class.getSimpleName();
            }
        },
        INTEGER {
            @Override
            public String getJavaType(String columnType) {
                return Integer.class.getSimpleName();
            }
        },
        LONG {
            @Override
            public String getJavaType(String columnType) {
                return Long.class.getSimpleName();
            }
        },
        NUMBER {
            @Override
            public String getJavaType(String columnType) {
                if(!columnType.contains(",")) {
                    return Long.class.getSimpleName();
                }
                return BigDecimal.class.getSimpleName();
            }
        };

        public abstract String getJavaType(String columnType);
    }

    private final String code;
    private final Type type;

}
